﻿using JsonHelper;
using KG.Neo4j;
using System;
using System.Collections.Generic;

namespace KG.SystemService
{
    public class RelationService
    {
        public Neo4jRepository _neo4jRepository = new Neo4jRepository("", "neo4j://localhost:7687", "neo4j", "fdbsn0607.");
        /// <summary>
        /// 添加关系
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public RelationDTO.OutputId AddRelation(RelationDTO.InputAdd req)
        {
            try
            {
                #region 处理输入数据
                req.Check();
                //属性json解析
                dynamic properties = JsonUtils.Deserialize(req.Properties);
                Dictionary<string, string> properties1 = JsonUtils.Deserialize<Dictionary<string, string>>(properties.ToString());
                string setStr = "";
                foreach (var v in properties1)
                {
                    string propertyBuilder = $"{v.Key}:\"{v.Value}\",";
                    setStr += propertyBuilder;
                }
                if (setStr.IndexOf(',', setStr.Length - 1) > 0)
                {
                    setStr = setStr.Remove(setStr.Length - 1, 1);
                }
                #endregion
                var id = _neo4jRepository.MatchNodeByProperty(req.type,req.startId,req.endId, setStr).Result;

                return new RelationDTO.OutputId { id = id };
            }
            catch (Exception)
            {
                throw new Exception("添加关系失败");
            }
        }
        /// <summary>
        /// 删除关系
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public RelationDTO.OutputId DeleteRelation(RelationDTO.InputDelete req)
        {
            try
            {
                req.Check();
                string condition = $"id(r)={req.id}";
                _neo4jRepository.DeleteRelation(condition);
                return new RelationDTO.OutputId { id = req.id };
            }
            catch (Exception)
            {
                throw new Exception("删除关系失败");
            }
        }
        /// <summary>
        /// 编辑关系
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public RelationDTO.OutputId UpdateRelation(RelationDTO.InputUpdate req)
        {
            try
            {
                req.Check();
                string condition = $"id(r)={req.id}";
                //待更新的属性
                dynamic properties = JsonUtils.Deserialize(req.Properties);
                Dictionary<string, string> properties1 = JsonUtils.Deserialize<Dictionary<string, string>>(properties.ToString());
                string setStr = "";
                foreach (var v in properties1)
                {
                    string propertyBuilder = $"r.{v.Key}=\"{v.Value}\",";
                    setStr += propertyBuilder;
                }
                if (setStr.IndexOf(',', setStr.Length - 1) > 0)
                {
                    setStr = setStr.Remove(setStr.Length - 1, 1);
                }
                //待删除的属性
                string removestr = "";
                foreach (var item in req.deleteProperty)
                {
                    string removeBulider = $"r.{item},";
                    removestr += removeBulider;
                }
                removestr = removestr.Remove(removestr.Length - 1, 1);
                //更新属性
                _neo4jRepository.UpdateRelationProPertie(condition, setStr,removestr);
                //更新标签，但id会变
                var id = _neo4jRepository.UpdateRelationLabels(condition, req.type).Result;
                return new RelationDTO.OutputId { id = id };
            }
            catch (Exception)
            {
                throw new Exception("编辑关系失败");
            }
        }
        /// <summary>
        /// 查询单个关系信息
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public RelationDTO.OutputGet GetRelation(RelationDTO.InputGet req)
        {
            try
            {
                req.check();
                var sourceNodeData = new NodeInfo();
                var targetNodeData = new NodeInfo();
                string condition = $"id(r)={req.id}";
                var a = _neo4jRepository.GetRelation(condition).Result;
                dynamic type = JsonUtils.Deserialize(a.Item1);
                dynamic b = JsonUtils.Deserialize(a.Item2[0]);
                Dictionary<string, string> properties1 = JsonUtils.Deserialize<Dictionary<string, string>>(b.ToString());
                //解析json
                dynamic node1 = JsonUtils.Deserialize(JsonUtils.Deserialize(a.Item3[0]).ToString());
                Data data1 = new Data
                {
                    id = node1.id.ToObject<string>(),
                    name = node1.Name.ToObject<string>()
                };
                //起始节点信息
                NodeInfo nodeInfo1 = new NodeInfo
                {
                    group = "nodes",
                    data = data1,
                    classes = node1.Color.ToObject<string>()
                };
                sourceNodeData=nodeInfo1;
                //解析json得到终止结点信息
                dynamic node2 = JsonUtils.Deserialize(JsonUtils.Deserialize(a.Item4[0]).ToString());
                Data data2 = new Data
                {
                    id = node2.id.ToObject<string>(),
                    name = node2.Name.ToObject<string>()
                };
                //终止节点信息
                NodeInfo nodeInfo2 = new NodeInfo
                {
                    group = "nodes",
                    data = data2,
                    classes = node2.Color.ToObject<string>()
                };
                targetNodeData = nodeInfo2;
                return new RelationDTO.OutputGet {id=req.id,type = type,properties = properties1,sourceData = sourceNodeData,targetData = targetNodeData };
            }
            catch (Exception)
            {
                throw new Exception("查看单个关系信息失败");
            }
        }
        /// <summary>
        /// 加载关系名列表
        /// </summary>
        /// <returns></returns>
        public RelationDTO.OutputTypeLoad TypeLoad()
        {
            try
            {
                var typeList =  _neo4jRepository.TypeLoad().Result;
                return new RelationDTO.OutputTypeLoad { types = typeList };
            }
            catch (Exception)
            {
                throw new Exception("加载关系类型名失败");
            }
        }
        /// <summary>
        /// 加载关系列表
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public RelationDTO.OutputLoad Load(RelationDTO.InputLoad req)
        {
            try
            {
                var relationDatas = new List<RelationInfo>();
                var nodeDatas = new List<NodeInfo>();
                //检索关系名
                if (req.loadType == 0)
                {
                    var relationList = _neo4jRepository.LoadRelations(req.key, req.limit).Result;
                    for (int i = 0; i < relationList.Item1.Count; i++)
                    {
                        //解析json
                        dynamic relation = JsonUtils.Deserialize(JsonUtils.Deserialize(relationList.Item1[i]).ToString());
                        relationData relationData = new relationData
                        {
                            id = relation.id.ToObject<string>(),
                            name = relation.name.ToObject<string>(),
                            source = relation.source.ToObject<string>(),
                            target = relation.target.ToObject<string>(),
                        };
                        RelationInfo relationInfo = new RelationInfo
                        {
                            group = "edges",
                            data = relationData
                        };
                        relationDatas.Add(relationInfo);
                    }
                    for (int i = 0; i < relationList.Item2.Count; i++)
                    {
                        //解析json
                        dynamic node1 = JsonUtils.Deserialize(JsonUtils.Deserialize(relationList.Item2[i]).ToString());
                        Data data1 = new Data
                        {
                            id = node1.id.ToObject<string>(),
                            name = node1.Name.ToObject<string>()
                        };
                        //起始节点信息
                        NodeInfo nodeInfo1 = new NodeInfo
                        {
                            group = "nodes",
                            data = data1,
                            classes = node1.Color.ToObject<string>()
                        };
                        nodeDatas.Add(nodeInfo1);
                    }
                }
                //模糊检索关系属性
                else
                {
                    var relationList = _neo4jRepository.LoadRelationsByProPerti(req.key, req.limit,req.property).Result;
                    for (int i = 0; i < relationList.Item1.Count; i++)
                    {
                        //解析json
                        dynamic relation = JsonUtils.Deserialize(JsonUtils.Deserialize(relationList.Item1[i]).ToString());
                        relationData relationData = new relationData
                        {
                            id = relation.id.ToObject<string>(),
                            name = relation.name.ToObject<string>(),
                            source = relation.source.ToObject<string>(),
                            target = relation.target.ToObject<string>(),
                        };
                        RelationInfo relationInfo = new RelationInfo
                        {
                            group = "edges",
                            data = relationData
                        };
                        relationDatas.Add(relationInfo);
                    }
                    for (int i = 0; i < relationList.Item2.Count; i++)
                    {
                        //解析json
                        dynamic node1 = JsonUtils.Deserialize(JsonUtils.Deserialize(relationList.Item2[i]).ToString());
                        Data data1 = new Data
                        {
                            id = node1.id.ToObject<string>(),
                            name = node1.Name.ToObject<string>()
                        };
                        //起始节点信息
                        NodeInfo nodeInfo1 = new NodeInfo
                        {
                            group = "nodes",
                            data = data1,
                            classes = node1.Color.ToObject<string>()
                        };
                        nodeDatas.Add(nodeInfo1);
                    }
                }
                return new RelationDTO.OutputLoad {data = relationDatas,nodeData = nodeDatas, limit = req.limit,total = relationDatas.Count };
            }
            catch (Exception)
            {
                throw new Exception("加载关系列表失败");
            }
        }
        /// <summary>
        /// 条件检索
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public RelationDTO.OutputLoad complexLoad(RelationDTO.InputComplexLoad req)
        {
            try
            {
                var relationDatas = new List<RelationInfo>();
                var nodeDatas = new List<NodeInfo>();
                string idCondition = "";
                string condition = "";
                //只针对首尾结点进行条件检索
                #region 处理id条件
                if (req.startId==null&&req.endId==null)
                {
                    idCondition = null;
                }
                else if(req.endId==null)
                {
                    idCondition += $"id(n1)={req.startId}";
                }
                else if (req.startId == null)
                {
                    idCondition += $"id(n{req.jump + 1})={req.endId}";
                }
                else
                {
                    idCondition += $"id(n1)={req.startId} and id(n{req.jump + 1})={req.endId}";
                }
                #endregion
                #region 处理条件语句
                if (req.cypher == null)
                {
                    condition = null;
                }
                else
                {
                    condition = req.cypher;
                }
                #endregion
                #region 数据查询+处理
                var relationList =_neo4jRepository.RelationComplexLoad(req.jump, idCondition,req.limit, condition,req.type).Result;
                for (int i = 0; i < relationList.Item1.Count; i++)
                {
                    //解析json
                    dynamic relation = JsonUtils.Deserialize(JsonUtils.Deserialize(relationList.Item1[i]).ToString());
                    relationData relationData = new relationData
                    {
                        id = relation.id.ToObject<string>(),
                        name = relation.name.ToObject<string>(),
                        source = relation.source.ToObject<string>(),
                        target = relation.target.ToObject<string>(),
                    };
                    RelationInfo relationInfo = new RelationInfo
                    {
                        group = "edges",
                        data = relationData
                    };
                    relationDatas.Add(relationInfo);
                }
                for (int i = 0; i < relationList.Item2.Count; i++)
                {
                    //解析json
                    dynamic node1 = JsonUtils.Deserialize(JsonUtils.Deserialize(relationList.Item2[i]).ToString());
                    Data data1 = new Data
                    {
                        id = node1.id.ToObject<string>(),
                        name = node1.Name.ToObject<string>()
                    };
                    //起始节点信息
                    NodeInfo nodeInfo1 = new NodeInfo
                    {
                        group = "nodes",
                        data = data1,
                        classes = node1.Color.ToObject<string>()
                    };
                    nodeDatas.Add(nodeInfo1);
                }
                    #endregion
                return new RelationDTO.OutputLoad { data = relationDatas, nodeData = nodeDatas, limit = req.limit, total = relationDatas.Count };
            }
            catch (Exception)
            {
                throw new Exception("条件检索失败");
            }
        }
    }

}
